package com.bite.rabbitmq.controller;


import com.bite.rabbitmq.constant.Constants;
import jakarta.annotation.Resource;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.AsyncRabbitTemplate;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
@RequestMapping("/producer")
public class ProducerController {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Resource(name = "confirmRabbitTemplate")
    private RabbitTemplate confirmRabbitTemplate;

    @Resource(name = "returnRabbitTemplate")
    private RabbitTemplate returnRabbitTemplate;

    @Resource(name = "transRabbitTemplate")
    private RabbitTemplate transRabbitTemplate;

    @RequestMapping("/ack")
    public String ack() {
        rabbitTemplate.convertAndSend(Constants.ACK_EXCHANGE, "ack", "rabbitmq ack test...");
        return "ack test...";
    }

    @RequestMapping("/pres")
    public String pres() {
        // 设置不是持久化的
        Message message = new Message("hello during rabbitMQ...".getBytes(), new MessageProperties());
        // 消息不持久化
        message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
        // 消息持久化
//        message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
        rabbitTemplate.convertAndSend(Constants.PRES_EXCHANGE, "pres", message);

        return "pres test...";
    }

    // 发送确认
    @RequestMapping("/confirm")
    public String confirm() {
        CorrelationData correlationData = new CorrelationData("1");
        confirmRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, "confirm", "confirm test...", correlationData);

        return "confirm test...";
    }

    // 消息退回
    @RequestMapping("/returns")
    public String returns() {
        CorrelationData correlationData = new CorrelationData("13");
        returnRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, "confirm111", "confirm test...", correlationData);

        return "returns test...";
    }

    // 重试
    @RequestMapping("/retry")
    public String retry() {
        rabbitTemplate.convertAndSend(Constants.RETRY_EXCHANGE, "retry", "hello retry...");
        return "retry test...";
    }

    // ttl
    @RequestMapping("/ttl")
    public String ttl() {
        // 先存入ttl比较长的 然后存入比较短的
        // 发现当短的时间到了的时候 依然没有消失
        // 直到它为队首元素的时候（ttl较长的已经销毁了） 才消失
        // 所以 如果前面的是一个没有设置ttl的消息 那么后面的是永远不会被销毁 除非成为队首元素
        rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE, "ttl", "ttl test30s...", message -> {
            // 设置销毁时间
            message.getMessageProperties().setExpiration("30000");
            return message;
        });
        // 加入到两个队列中（一个ttl为20s 一个是默认） 同时消失
        rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE, "ttl", "ttl test20s...", message -> {
            // 设置销毁时间
            message.getMessageProperties().setExpiration("10000");
            return message;
        });
        return "ttl test...";
    }
    @RequestMapping("/ttl2")
    public String ttl2() {
        rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE, "ttl", "ttl test...");
        return "ttl test...";
    }

    @RequestMapping("/dl")
    public String dl() {
        // 正常发送
        rabbitTemplate.convertAndSend(Constants.NORMAL_EXCHANGE, "normal", "dl test...");
        System.out.println(new Date() + " 发送了消息");
        return "dl test...";
    }
    @RequestMapping("/dl2")
    public String dl2() {
        // 死信出现三种情况： 1. 超时 2. 消息被拒绝并且不重新入队 3. 超出队列最大限度
        for (int i = 0; i < 20; i++) {
            rabbitTemplate.convertAndSend(Constants.NORMAL_EXCHANGE, "normal", "dl test..." + i);
        }
        return "dl test...";
    }

    // 延迟队列（通过延迟发送到queue来实现）
    @RequestMapping("/delay")
    public String delay() {
        System.out.println("在 " + new Date() + " 发送消息");
        // 30s延迟
        rabbitTemplate.convertAndSend(Constants.DELAY_EXCHANGE, "delay", "delay 10s test...", message -> {
            message.getMessageProperties().setDelayLong(10000L);
            return message;
        });
        // 10s延迟
        rabbitTemplate.convertAndSend(Constants.DELAY_EXCHANGE, "delay", "delay 30s test...", message -> {
            message.getMessageProperties().setDelayLong(30000L);
            return message;
        });

        return "delay test...";
    }

    // 事务
    @Transactional // 设置注解
    @RequestMapping("/trans")
    public String trans() {
        System.out.println("hello");
        transRabbitTemplate.convertAndSend("", Constants.TRANS_QUEUE, "trans test1...");
        int i = 1/0;
        transRabbitTemplate.convertAndSend("", Constants.TRANS_QUEUE, "trans test2...");
        return "trans test...";
    }

    // 限流
    @RequestMapping("/qos")
    public String qos() {
        for (int i = 0; i < 20; i++) {
            rabbitTemplate.convertAndSend(Constants.QOS_EXCHANGE, "qos", "qos test..." + i);
        }
        return "qos test...";
    }
}
